package com.xwd.utils;

import org.apache.log4j.Logger;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Vector;

/**
 * @ClassName JDBCUtils
 * @Description: com.xwd.utils-获取数据库连接
 * @Auther: xiwd
 * @Date: 2022/2/13 - 02 - 13 - 13:27
 * @version: 1.0
 */
public class ConnectionPool implements DataSource{
    //static properties
    private static final String DRIVER;
    private static final String URL;
    private static final String USERNAME;
    private static final String PASSWORD;
    private static final int minSize;
    private static final int maxSize;
    //
    private static PropertyUtil propertyUtil;
    private static Logger logger;
    private static Vector<Connection> pools;

    //static block
    static {
        //实例化Logger
        logger = Logger.getLogger(ConnectionPool.class);
        //加载jdbc.properties配置文件
        propertyUtil=new PropertyUtil("/jdbc.properties");
        //初始化静态属性
        DRIVER = propertyUtil.getPropertyValue("driver");
        URL = propertyUtil.getPropertyValue("url");
        USERNAME = propertyUtil.getPropertyValue("username");
        PASSWORD = propertyUtil.getPropertyValue("password");
        minSize = Integer.valueOf(propertyUtil.getPropertyValue("minSize"));
        maxSize = Integer.valueOf(propertyUtil.getPropertyValue("maxSize"));
        //注册jdbc驱动
        try {
            Class.forName(DRIVER);
            logger.info("JDBC Driver init SUCCESSFULLY!");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            logger.fatal("JDBC Driver init FAILED!");
        }
        //初始化数据库连接池
        pools = new Vector<>();
        //生成最小数据库连接通道
        for (int i = 0; i < minSize; i++) {
            Connection connection = initConnection();
            pools.add(connection);
        }
    }

    //methods
    /**
     * 获取数据库连接Connection对象
     * @return Connection对象
     */
    private static synchronized Connection initConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(URL,USERNAME,PASSWORD);
            logger.info("Connection "+connection.hashCode()+" init Completed!");
        } catch (SQLException e) {
            e.printStackTrace();
            logger.warn("Connection "+connection.hashCode()+" init FAILED!");
        }
        return connection;
    }

    /**
     * 向用户提供数据库连接Connection对象
     * @return Connection对象
     */
    public static Connection popConnection(){
        Connection connection = null;
        //判断当前数据库连接池中是否有>=1个Connection对象
        if (pools.size()>0)
            connection = pools.remove(0);
        else
            connection = initConnection();
        return connection;
    }



    /**
     * 返还数据库连接Connection对象
     * @param connection 数据库连接对象
     * @return true-返还成功;false-返还失败
     */
    public static void pushConnection(Connection connection){
        //判空处理
        if (connection==null){
            logger.warn("OPERATION was denied because connection is null");
            return;
        }
        try {
            //判断Connection对象是否已经关闭
            if (connection.isClosed()){
                logger.info("connection - "+connection.hashCode()+" has been closed");
                return;
            }
            //修改事务处理模式为——自动提交模式
            connection.setAutoCommit(true);
            //执行数据库返还操作
            if (pools.size()<maxSize){
                pools.add(connection);
                logger.info("connection - "+connection.hashCode()+" has been returned");
            }else {
                connection.close();
                logger.info("connection - "+connection.hashCode()+" has been released");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Connection getConnection() throws SQLException {
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}
